#!/usr/bin/env python3
"""
Hyperliquid Trading Bot Launcher

Simple launcher script for the Hyperliquid trading bot with strategy selection.
"""

import asyncio
import logging
import sys
from typing import Dict, Any

from config.settings import Config
from config.api_config import APIConfig
from connectors.hyperliquid.hyperliquid_spot_connector import HyperliquidSpotConnector
from connectors.hyperliquid.hyperliquid_perpetual_connector import HyperliquidPerpetualConnector
from strategies.hyperliquid_grid_strategy import HyperliquidGridStrategy
from strategies.hyperliquid_funding_arbitrage import HyperliquidFundingArbitrageStrategy
from strategies.strategy_config import StrategyConfigManager


class TradingBotLauncher:
    """
    Trading bot launcher with strategy selection
    """
    
    def __init__(self):
        self.config = Config()
        self.api_config = APIConfig()
        self.strategy_config = StrategyConfigManager()
        self.logger = self._setup_logging()
        
        # Connectors
        self.connectors: Dict[str, Any] = {}
        self.strategy = None
    
    def _setup_logging(self) -> logging.Logger:
        """Setup logging configuration"""
        logging.basicConfig(
            level=logging.INFO,
            format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
            handlers=[
                logging.StreamHandler(sys.stdout),
                logging.FileHandler('trading_bot.log')
            ]
        )
        return logging.getLogger(__name__)
    
    def display_banner(self):
        """Display welcome banner"""
        banner = """
╔══════════════════════════════════════════════════════════════╗
║                  Hyperliquid Trading Bot                    ║
║                 基于 Hummingbot 框架开发                     ║
╠══════════════════════════════════════════════════════════════╣
║  支持功能:                                                   ║
║  • 现货交易 (Spot Trading)                                  ║
║  • 永续合约交易 (Perpetual Trading)                         ║
║  • 网格交易策略 (Grid Trading Strategy)                     ║
║  • 资金费率套利策略 (Funding Rate Arbitrage)                ║
╚══════════════════════════════════════════════════════════════╝
        """
        print(banner)
    
    def display_strategy_menu(self) -> str:
        """Display strategy selection menu"""
        menu = """
请选择交易策略 (Please select a trading strategy):

1. 网格交易策略 (Grid Trading Strategy)
   - 适用于震荡市场
   - 通过网格订单获取价差收益
   - 支持现货和永续合约

2. 资金费率套利策略 (Funding Rate Arbitrage Strategy)
   - 利用现货与永续合约资金费率差异
   - 自动对冲管理
   - 适用于高资金费率环境

3. 退出 (Exit)

请输入选择 (1-3): """
        
        print(menu)
        choice = input().strip()
        return choice
    
    def display_config_summary(self):
        """Display current configuration summary"""
        print("\n" + "="*60)
        print("当前配置摘要 (Current Configuration Summary)")
        print("="*60)
        print(f"交易对 (Trading Pair): {self.config.TRADING_PAIR}")
        print(f"测试模式 (Test Mode): {self.config.TEST_MODE}")
        print(f"测试网 (Testnet): {self.api_config.testnet}")
        
        if hasattr(self.config, 'GRID_LEVELS'):
            print(f"网格层数 (Grid Levels): {self.config.GRID_LEVELS}")
            print(f"网格间距 (Grid Spread): {self.config.GRID_SPREAD * 100}%")
        
        if hasattr(self.config, 'MIN_FUNDING_RATE'):
            print(f"最小资金费率 (Min Funding Rate): {self.config.MIN_FUNDING_RATE * 100}%")
        
        print("="*60)
    
    async def initialize_connectors(self):
        """Initialize exchange connectors"""
        self.logger.info("Initializing connectors...")
        
        try:
            # Get trading pairs from config
            trading_pairs = [self.config.TRADING_PAIR]
            
            # Initialize spot connector
            self.connectors["hyperliquid_spot"] = HyperliquidSpotConnector(
                trading_pairs=trading_pairs,
                config=self.config
            )
            
            # Initialize perpetual connector
            self.connectors["hyperliquid_perpetual"] = HyperliquidPerpetualConnector(
                trading_pairs=trading_pairs,
                trading_required=True
            )
            
            # Start connectors
            for name, connector in self.connectors.items():
                await connector.start_network()
                self.logger.info(f"Started {name} connector")
            
            self.logger.info("All connectors initialized successfully")
            
        except Exception as e:
            self.logger.error(f"Failed to initialize connectors: {e}")
            raise
    
    async def initialize_strategy(self, strategy_choice: str):
        """Initialize selected strategy"""
        self.logger.info(f"Initializing strategy: {strategy_choice}")
        
        try:
            if strategy_choice == "1":
                # Grid Trading Strategy
                self.strategy = HyperliquidGridStrategy(self.connectors)
                self.logger.info("Grid Trading Strategy initialized")
                
            elif strategy_choice == "2":
                # Funding Rate Arbitrage Strategy
                self.strategy = HyperliquidFundingArbitrageStrategy(self.connectors)
                self.logger.info("Funding Rate Arbitrage Strategy initialized")
                
            else:
                raise ValueError(f"Invalid strategy choice: {strategy_choice}")
            
        except Exception as e:
            self.logger.error(f"Failed to initialize strategy: {e}")
            raise
    
    async def run_strategy(self):
        """Run the selected strategy"""
        if not self.strategy:
            raise ValueError("No strategy initialized")
        
        self.logger.info("Starting strategy execution...")
        print("\n策略已启动! 按 Ctrl+C 停止交易机器人")
        print("Strategy started! Press Ctrl+C to stop the trading bot\n")
        
        try:
            # Start strategy
            await self.strategy.start()
            
            # Keep running until interrupted
            while True:
                await asyncio.sleep(1)
                
                # Display strategy status every 30 seconds
                if hasattr(self.strategy, 'format_status'):
                    status = self.strategy.format_status()
                    if status:
                        print(f"\n{status}\n")
                
                await asyncio.sleep(30)
                
        except KeyboardInterrupt:
            self.logger.info("Received interrupt signal, stopping strategy...")
            print("\n正在停止策略... (Stopping strategy...)")
            
        except Exception as e:
            self.logger.error(f"Strategy execution error: {e}")
            raise
        
        finally:
            # Stop strategy
            if hasattr(self.strategy, 'stop'):
                await self.strategy.stop()
            
            # Stop connectors
            for name, connector in self.connectors.items():
                try:
                    await connector.stop_network()
                    self.logger.info(f"Stopped {name} connector")
                except Exception as e:
                    self.logger.error(f"Error stopping {name} connector: {e}")
    
    def validate_configuration(self) -> bool:
        """Validate configuration before starting"""
        try:
            # Check API credentials
            if not self.api_config.private_key or not self.api_config.wallet_address:
                print("❌ 错误: API 凭据未配置")
                print("❌ Error: API credentials not configured")
                print("请在环境变量中配置您的私钥和钱包地址")
                print("Please configure your private key and wallet address in environment variables")
                return False
            
            # Check trading pair
            if not self.config.TRADING_PAIR or "-" not in self.config.TRADING_PAIR:
                print("❌ 错误: 交易对配置无效")
                print("❌ Error: Invalid trading pair configuration")
                return False
            
            print("✅ 配置验证通过 (Configuration validation passed)")
            return True
            
        except Exception as e:
            print(f"❌ 配置验证失败: {e}")
            print(f"❌ Configuration validation failed: {e}")
            return False
    
    async def run(self):
        """Main run method"""
        try:
            # Display banner
            self.display_banner()
            
            # Validate configuration
            if not self.validate_configuration():
                return
            
            # Display configuration summary
            self.display_config_summary()
            
            # Strategy selection loop
            while True:
                choice = self.display_strategy_menu()
                
                if choice == "3":
                    print("退出程序... (Exiting...)")
                    break
                
                if choice in ["1", "2"]:
                    try:
                        # Initialize connectors
                        await self.initialize_connectors()
                        
                        # Initialize strategy
                        await self.initialize_strategy(choice)
                        
                        # Run strategy
                        await self.run_strategy()
                        
                        break
                        
                    except Exception as e:
                        self.logger.error(f"Error running strategy: {e}")
                        print(f"\n❌ 策略运行错误: {e}")
                        print(f"❌ Strategy execution error: {e}")
                        
                        # Ask if user wants to try again
                        retry = input("\n是否重试? (y/n) / Retry? (y/n): ").strip().lower()
                        if retry not in ['y', 'yes', '是']:
                            break
                else:
                    print("❌ 无效选择，请重新输入")
                    print("❌ Invalid choice, please try again")
        
        except Exception as e:
            self.logger.error(f"Launcher error: {e}")
            print(f"\n❌ 启动器错误: {e}")
            print(f"❌ Launcher error: {e}")
        
        finally:
            print("\n感谢使用 Hyperliquid Trading Bot!")
            print("Thank you for using Hyperliquid Trading Bot!")


async def main():
    """Main entry point"""
    launcher = TradingBotLauncher()
    await launcher.run()


if __name__ == "__main__":
    try:
        asyncio.run(main())
    except KeyboardInterrupt:
        print("\n程序被用户中断 (Program interrupted by user)")
    except Exception as e:
        print(f"\n程序异常退出: {e}")
        print(f"Program exited with error: {e}")